package com.bcdat.sso_user_management.exception;

import com.bcdat.sso_user_management.comm.ParamInvalidItem;
import com.bcdat.sso_user_management.comm.Result;
import com.bcdat.sso_user_management.comm.ResultCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.validation.ConstraintViolationException;
import java.util.ArrayList;
import java.util.List;

/**
 * @author zhaolele
 * @date 2019-09-19 13:52
 */
@Slf4j
@RestController
@ControllerAdvice
public class GlogbalExceptionHandler {

    /**
     * 违反约束异常
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(ConstraintViolationException.class)
    protected Result handleConstraintViolationException(ConstraintViolationException e, HttpServletRequest request) {
        log.info("违反约束异常， rui: {}, 异常: {} ", request.getRequestURI(), e);

        return Result.failure(ResultCode.PARAM_IS_INVALID);
    }

    /**
     * 处理验证参数封装错误时异常
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Result handleMethodArgumentNotValidException(MethodArgumentNotValidException e, HttpServletRequest request) {
        log.warn("请求参数错误， rui: {}, 异常: {} ", request.getRequestURI(), e);
        List<FieldError> fieldErrors = e.getBindingResult().getFieldErrors();
        ArrayList<ParamInvalidItem> paramInvalidItems = new ArrayList<>();
        fieldErrors.forEach(fieldError -> {
            paramInvalidItems.add(new ParamInvalidItem(fieldError.getField(), fieldError.getDefaultMessage()));
        });
        return Result.failure(ResultCode.PARAM_IS_INVALID, paramInvalidItems);
    }

    /**
     * 处理业务异常
     * @param e
     * @param request
     * @return
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(BusinessException.class)
    public Result handleBusinessException(BusinessException e, HttpServletRequest request) {
        return Result.failure(e.getResultCode());
    }

    /**
     * 处理运行时系统异常（500错误码）
     */
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ExceptionHandler(Exception.class)
    protected Result handleRuntimeException(Exception e, HttpServletRequest request) {
        log.error("服务器内部异常, uri:{}, 异常: ", request.getRequestURI(), e);

        return Result.failure(ResultCode.INTERNAL_SYSTEM_ERROR);
    }
}
